iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
AI & Data

ML From Scratch系列 第 12

[Day 12] K nearest neighbors — 主題實作

  • 分享至 

  • xImage
  •  

了解完 K nearest neighbors 的理論後,我們今天會透過著名的 iris 資料集來實做它。

Implementation

Import Library

首先透過使用 scikit-learn 的 library 來實做

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns

Load Dataset

iris = pd.read_csv("../input/iris/Iris.csv") #Load Data
iris.drop('Id',inplace=True,axis=1) #Drop Id column

這裡注意到,資料集的路徑必須隨檔案路徑更改

之後移除不必要的 column Id

X = iris.iloc[:,:-1] #Set our training data
y = iris.iloc[:,-1] #Set training labels

定義資料集的資料跟標籤

Divide the data into train and test

X_train, X_test, y_train, y_test = train_test_split(X.values, y.values, test_size = 0.2, random_state=42) #split the  data into traing and validating

Sklearn Implementation

from sklearn.neighbors import KNeighborsClassifier
skmodel = KNeighborsClassifier(n_neighbors=7)
skmodel.fit(X_train, y_train)

sk_predictions = skmodel.predict(X_test)
sk_accuracy = compute_accuracy(y_test, sk_predictions)
print(f" sklearn-model got accuracy score of : {sk_accuracy}")

k 值目前設 7

這裡我們得到使用 KNN 分類的準確率是 96.67 %

KNN from Scratch

class KNN:
    def __init__(self, n_neighbors=5):
        self.n_neighbors = n_neighbors
        
    def euclidean_distance(self, x1, x2):
        return np.linalg.norm(x1 - x2)

    def fit(self, X_train, y_train):
        self.X_train = X_train
        self.y_train = y_train

    def predict(self, X):
        # Create empty array to store the predictions
        predictions = []
        # Loop over X examples
        for x in X:
            # Get prediction using the prediction helper function
            prediction = self._predict(x)
            # Append the prediction to the predictions list
            predictions.append(prediction)
        return np.array(predictions)

    def _predict(self, x):
        # Create empty array to store distances
        distances = []
        # Loop over all training examples and compute the distance between x and all the training examples 
        for x_train in self.X_train:
            distance = self.euclidean_distance(x, x_train)
            distances.append(distance)
        distances = np.array(distances)
        
        # Sort by ascendingly distance and return indices of the given n neighbours
        n_neighbors_idxs = np.argsort(distances)[: self.n_neighbors]
        
        # Get labels of n-neighbour indexes
        labels = self.y_train[n_neighbors_idxs]                  
        labels = list(labels)
        # Get the most frequent class in the array
        most_occuring_value = max(labels, key=labels.count)
        return most_occuring_value

__init__(self, n_neighbors)

定義 k 的初始值

euclidean_distance(self, x1, x2)

計算歐幾里得距離

假設 https://chart.googleapis.com/chart?cht=tx&chl=n 維點,點 https://chart.googleapis.com/chart?cht=tx&chl=x%20%3D%20(x_1%2C%20%5Cdots%2C%20x_n)https://chart.googleapis.com/chart?cht=tx&chl=y%20%3D%20(y_1%2C%20%5Cdots%2C%20y_n),而其歐氏距離為

https://chart.googleapis.com/chart?cht=tx&chl=d(x%2C%20y)%20%3D%20%5Csqrt%7B(x_1%20-%20y_1)%5E2%20%2B%20(x_2%20-%20y_2)%5E2%20%2B%20%5Cdots%20%2B%20(x_n%20-%20y_n)%5E2%7D

fit(self, X_train, y_train)

此處接收訓練數據集 X_train 和對應的目標標籤 y_train

它將訓練數據集和目標標籤存儲在類別的實例變數 self.X_trainself.y_train 中,以供後續使用。

predict(self, X)

此處接收測試數據集 X,並返回對每個測試數據點的預測類別標籤。

它遍歷測試數據集中的每個數據點 x,並調用 _predict 方法來獲得每個數據點的預測類別。

_predict(self, x)

首先計算測試點 x 與訓練數據集中每個訓練點之間的歐式距離,並將這些距離存儲在 distances 列表中。

然後,使用 argsort 函數對距離列表進行排序,以獲得最接近 x 的前 n_neighbors 個鄰居的索引。

接下來,從訓練數據集中檢索這些鄰居的標籤,並將這些標籤存儲在 labels 列表中。

最後找到 labels 中出現最頻繁的類別標籤,並將其視為 x 的預測類別標籤,然後回傳這個預測類別。

與前面 Sklearn Implementation 一樣,我們得到使用 KNN 分類的準確率是 96.67 %


詳細 Notebook 可以參考 Kaggle

明天要進入真實實戰部份,會透過 Kaggle competition - Spaceship Titanic 來演練

/images/emoticon/emoticon06.gif

Reference


上一篇
[Day 11] K nearest neighbors — 背後理論
下一篇
[Day 13] K nearest neighbors — 解決真實問題
系列文
ML From Scratch31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言